#ifndef __SERVICE_PROXY_ASYNC_SERVICE_H__
#define __SERVICE_PROXY_ASYNC_SERVICE_H__

#include "../IServiceProxy.h"
#include "asyncservice.grpc.pb.h"
#include <map>
#include <boost/function.hpp>
#include <boost/atomic.hpp>
#include <boost/enable_shared_from_this.hpp>

class BaseProxy{
public:
    int seq = 0;
    boost::function<void ()> funNext;
};
typedef boost::shared_ptr<BaseProxy> BaseProxyPtr;


class ServiceProxyAsyncService : public IServerProxy, public boost::enable_shared_from_this<ServiceProxyAsyncService>{
public:
    typedef boost::shared_ptr<cecily::Student> student_request_ptr;
    typedef boost::shared_ptr<grpc::ServerAsyncResponseWriter<cecily::Teacher>> student_proxy_ptr;

    typedef boost::shared_ptr<cecily::Teacher> teacher_request_ptr;
    typedef boost::shared_ptr<grpc::ServerAsyncResponseWriter<cecily::Student>> teacher_proxy_ptr;

    typedef std::shared_ptr<grpc::ServerCompletionQueue> queue_ptr;

    ServiceProxyAsyncService();
    virtual bool addListen();
    virtual void notify(void* tag);
    virtual grpc::Service* getService();
    virtual void stop();
protected:
    template<typename T1, typename T2, typename T3>
    void deleteFromMap(T1, T2, T3){
    };

    virtual void handleStudentListen();
    virtual void handleStudentWork(student_request_ptr pRequest, teacher_request_ptr pResponse, student_proxy_ptr pProxy);
    virtual void handleTeacherListen();
    virtual void handleTeacherWork(teacher_request_ptr pRequest, student_request_ptr pResponse, teacher_proxy_ptr pProxy);


    grpc::ServerContext m_context;
    queue_ptr m_pQueue;
    cecily::School::AsyncService m_service;
    std::map<int, BaseProxyPtr > m_MapProxy;
    boost::atomic_int m_seq;
};





#endif